package com.jeasonzhao.web;

import java.io.Serializable;
import java.util.Hashtable;

import com.jeasonzhao.commons.basic.StringCollection;
import com.jeasonzhao.commons.json.JSONArray;
import com.jeasonzhao.commons.json.JSONClass;
import com.jeasonzhao.commons.json.JSONException;
import com.jeasonzhao.commons.json.JSONNode;
import com.jeasonzhao.commons.utils.Algorithms;
import com.jeasonzhao.commons.utils.ConvertEx;
import com.jeasonzhao.commons.xml.XMLAttribute;
import com.jeasonzhao.commons.xml.XMLException;
import com.jeasonzhao.commons.xml.XMLHelper;
import com.jeasonzhao.commons.xml.XMLNode;
import com.jeasonzhao.model.ModelException;
import com.jeasonzhao.model.ModelHelper;

public class ToolbarItem implements Serializable
{
    private static final long serialVersionUID = 1L;
    private static final String[] TITLES = new String[]
        {"text","title","name"};
    private static final String[] IDS = new String[]
        {"id","key","value"};
    private static final String[] SELECTEDS = new String[]
        {"checked","selected","check","select"};
    private static final String[] HANDLERS = new String[]
        {"handler","onclick","click","url","href"};
    private static final String[] ICONS = new String[]
        {"iconCls","icon","icons","img","images"};
    private static final String[] STATES = new String[]
        {"state","status"};
    private static final String[] PROPERTIES = new String[]
        {"attributes","attribute","properties","property","memebers","member"};
    private static final String[] SUBITEMS = new String[]
        {"children","nodes","subnodes","items","subitems","subs"};
    private static final String[] PURETEXTNODES = new String[]
        {"span","font","b","p","A","option"};
    private static String[] KEYWORDS = null;
    static
    {
        StringCollection coll = new StringCollection();
        coll.add2(TITLES);
        coll.add2(IDS);
        coll.add2(SELECTEDS);
        coll.add2(HANDLERS);
        coll.add2(ICONS);
        coll.add2(STATES);
        coll.add2(PROPERTIES);
        KEYWORDS = new String[coll.size()];
        coll.copyInto(KEYWORDS);
    }

    private String id = null;
    private String text = null;
    private String handler = null;
    private String icon = null;
    private String state = null;
    private boolean selected = false;
    private Object tag=null;
    private ToolbarItemCollection items = new ToolbarItemCollection();
    private java.util.Hashtable<String,String> properties = new java.util.Hashtable<String,String>();
    private ToolbarItem parentItem=null;
    public ToolbarItem()
    {
        super();
    }
    public ToolbarItem(ToolbarItem parentNode)
    {
        super();
        this.parentItem=parentNode;
    }
    public ToolbarItem addProperty(String name,String value)
    {
        if(null != name && name.trim().length() > 0)
        {
            if(null == value || value.trim().length() < 1)
            {
                properties.remove(name.trim());
            }
            else
            {
                properties.put(name.trim(),value.trim());
            }
        }
        return this;
    }
    public void setParentItem(ToolbarItem pa)
    {
        this.parentItem=pa;
    }
    public ToolbarItem getParentItem()
    {
        return this.parentItem;
    }
    public static final ToolbarItem from(ToolbarItem parent,String str)
        throws XMLException,JSONException
    {
        if(Algorithms.isEmpty(str))
        {
            return null;
        }
        if(Algorithms.isXmlString(str))
        {
            return from(parent,XMLHelper.fromString(str));
        }
        else
        {
            return from(parent,JSONClass.from(str));
        }
    }

    public static final ToolbarItem fromObject(ToolbarItem parent,Object obj)
        throws ModelException
    {
        if(null == obj)
        {
            return null;
        }
        else
        {
            return from(parent,(JSONClass) ModelHelper.getInstance().toJSON(obj));
        }
    }

    public static final ToolbarItem from(ToolbarItem parent,JSONClass node)
    {
        if(null == node)
        {
            return null;
        }
        else
        {
            ToolbarItem item = new ToolbarItem(parent);
            item.setHandler(node.valueOf(HANDLERS));
            item.setIcon(node.valueOf(ICONS));
            item.setId(node.valueOf(IDS));
            item.setSelected(ConvertEx.toBool(node.valueOf(SELECTEDS)));
            item.setState(node.valueOf(STATES));
            item.setText(node.valueOf(TITLES));
            for(String pname : node.getVariableNames().removeItems(KEYWORDS))
            {
                item.addProperty(pname,node.valueOf(pname));
            }
            JSONNode subNode = node.getNode(PROPERTIES);
            JSONClass arrtNode = subNode == null || subNode.isJSONClass() ? null : (JSONClass) subNode;
            if(null != arrtNode)
            {
                for(String pname : arrtNode.getVariableNames())
                {
                    item.addProperty(pname,arrtNode.valueOf(pname));
                }
            }
            subNode = node.getNode(SUBITEMS);
            if(null != subNode && subNode.isJSONArray())
            {
                for(JSONNode c : ((JSONArray) subNode).items())
                {
                    if(c.isJSONClass())
                    {
                        item.add(from(item,(JSONClass) c));
                    }
                }
            }
            return item;
        }
    }

    public static final ToolbarItem from(ToolbarItem parent,XMLNode node)
    {
        if(null == node)
        {
            return null;
        }
        else
        {
            ToolbarItem item = new ToolbarItem(parent);
            String title = node.valueOf(TITLES);
            if(Algorithms.isEmpty(title))
            {
                title = node.getInnerText();
            }
            if(Algorithms.isEmpty(title))
            {
                title = node.getSubItemInnerText(PURETEXTNODES);
            }
            if(Algorithms.isEmpty(title))
            {
                title = node.guessInnerText();
            }
            item.setText(title);
            item.setId(node.valueOf(IDS));
            item.setSelected(ConvertEx.toBool(node.valueOf(SELECTEDS)));
            item.setHandler(node.valueOf(HANDLERS));
            item.setState(node.valueOf(STATES));
            item.setIcon(node.valueOf(ICONS));
            //Fill with attributes
            for(XMLAttribute attr : node.getAttributesExclude(KEYWORDS))
            {
                item.addProperty(attr.getName(),attr.getValue());
            }
            for(XMLNode nodeSubUL : node.selectNodes("UL","ITEMS","CHILD","CHILDREN","ITEM","FOLDER"))
            {
                for(XMLNode nodeSub : nodeSubUL.selectNodes("LI","ITEM","CHILD","SUB"))
                {
                    item.add(from(item,nodeSub));
                }
            }
            return item;
        }
    }

    public ToolbarItem add(ToolbarItem item)
    {
        if(null != item)
        {
            items.add(item);
            item.setParentItem(this);
        }
        return this;
    }

    public ToolbarItemCollection getItems()
    {
        return this.items;
    }

    public String getHandler()
    {
        return handler;
    }

    public String getIcon()
    {
        return icon;
    }

    public String getId()
    {
        return id;
    }

    public String getText()
    {
        return text;
    }

    public boolean isSelected()
    {
        return selected;
    }

    public Hashtable<String,String> getProperties()
    {
        return properties;
    }

    public String getState()
    {
        return state;
    }

    public Object getTag()
    {
        return tag;
    }

    public ToolbarItem setText(String value)
    {
        this.text = null == value || value.trim().length() < 1 ? null : value.trim();
        return this;
    }

    public ToolbarItem setId(String value)
    {
        this.id = null == value || value.trim().length() < 1 ? null : value.trim();
        return this;
    }

    public ToolbarItem setHandler(String value)
    {
        this.handler = null == value || value.trim().length() < 1 ? null : value.trim();
        return this;
    }

    public ToolbarItem setSelected(boolean selected)
    {
        this.selected = selected;
        return this;
    }

    public ToolbarItem setIcon(String value)
    {
        this.icon = null == value || value.trim().length() < 1 ? null : value.trim();
        return this;
    }

    public ToolbarItem setItems(ToolbarItemCollection items)
    {
        this.items = items;
        return this;
    }

    public ToolbarItem setProperties(Hashtable<String,String> properties)
    {
        this.properties = properties;
        return this;
    }

    public ToolbarItem setState(String value)
    {
        this.state = null == value || value.trim().length() < 1 ? null : value.trim();
        return this;
    }

    public void setTag(Object tag)
    {
        this.tag = tag;
    }

    public ToolbarItem cleanSelection()
    {
        this.setSelected(false);
        for(ToolbarItem item : this.items)
        {
            item.setSelected(false);
            if(null != item.getItems())
            {
                item.getItems().cleanSelection();
            }
        }
        return this;
    }

    public ToolbarItem cleanState()
    {
        this.setState(null);
        for(ToolbarItem item : this.items)
        {
            item.setState(null);
            if(null != item.getItems())
            {
                item.getItems().cleanState();
            }
        }
        return this;
    }

    public ToolbarItem findItemById(String id)
    {
        if(Algorithms.isEmpty(id))
        {
            return null;
        }
        if(id.equals(this.getId()))
        {
            return this;
        }
        for(ToolbarItem item : this.items)
        {
            if(null != item && id.equals(item.getId()))
            {
                return item;
            }
            else
            {
                ToolbarItem sub = item == null || item.getItems() == null
                    ? null : item.getItems().findItemById(id);
                if(null != sub)
                {
                    return sub;
                }
            }
        }
        return null;
    }
    public boolean containsChildren()
    {
        return this.items != null && this.items.size() > 0;
    }
}
